import axios from 'axios'
// js文件中不可使用$message
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router'
import { getToken } from './auth'

// 1.实例化 create方法
// 定制axios的基地址和超时时间
// 基地址？ 项目大部分接口前协议端口号是一致的，只有后面的相对路径不同
// 超时时间？ 接口从发送到接收允许的最大时差

const service = axios.create({
  // baseURL: process.env.VUE_APP_BASE_URL,
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000 // request timeout
})

// 请求拦截器
// 请求发送前对接口参数做一些配置
// 具体：注入token 在请求头 -> 为了大部分需要鉴权的接口能够统一获取用户标志
service.interceptors.request.use(
  config => {
    // const token = store.state.user.token
    const token = getToken()
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    // 一定要写return
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
// 数据返回到客户端时被拦截，
// 具体：1.token失效 强制跳转到登录页  2.简化组件中请求数据的访问
// 注意：
// 状态码2XX执行response方法，response.data服务端返回的响应数据
// 状态码不在200-300间执行error方法 error.response.data服务端返回的响应数据

// 如果后端自定义的http状态码不符合2xx-3xx来标识接口是否成功
// 这时和axios拦截器的成功和失败的判断依据是不一致的，会导致一个比较严重的问题，如果接口已经错了，axios依旧走的是成功回调，会导致不抛出错误，静默通过
// 这时，可以在响应拦截器中做后端自定义标志的判断：
// 1.成功：return response.data
// 2.失败：手动抛出错误return Promise.reject(message)
service.interceptors.response.use(
  response => {
    // 解构后端字段
    // success: 接口是否成功
    // data: 接口数据
    // message: 接口提示文案
    const { success, data, message } = response.data
    if (success) {
      return data
    } else {
      Message.warning(message)
      return Promise.reject(message)
    }
  },
  error => {
    // token失效处理
    // dir:可以展开对象
    console.dir(error)
    if (error.response && error.response.status === 401) {
      // 1. 清理失效的数据
      store.commit('user/removeUserInfo')
      // 2. 跳回到登录
      router.push({
        path: '/login'
      })
    }
    return Promise.reject(error)
  }
)

export default service
